#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
iOS应用分析器
"""

from pathlib import Path
from typing import Dict, List, Any, Optional
from datetime import datetime
import re
import os
import logging
import plistlib
import time

from src.analyzers.base import BaseAnalyzer
from src.models.result import AnalysisResult, FrameworkInfo, AppInfo
from src.utils.logger import get_logger

class IOSAnalyzer(BaseAnalyzer):
    """iOS应用程序分析器"""

    # iOS应用程序框架签名
    FRAMEWORK_SIGNATURES = {
        "UIKit": {
            "file_patterns": [r"\.nib$", r"\.storyboard$", r"UIViewController", r"UIView"],
            "search_patterns": [r"import\s+UIKit", r"UIViewController", r"UIView"],
            "category": "UI",
            "is_main_framework": True,
            "related_frameworks": ["Foundation", "CoreGraphics"]
        },
        "SwiftUI": {
            "file_patterns": [r"View\.swift$"],
            "search_patterns": [r"import\s+SwiftUI", r"struct.*:.*View", r"@main.*App"],
            "category": "UI",
            "is_main_framework": True,
            "related_frameworks": ["Combine", "Swift"]
        },
        "Flutter": {
            "file_patterns": [r"flutter\.json", r"\.dart$"],
            "search_patterns": [r"package:flutter", r"Flutter", r"Widget"],
            "category": "Cross-Platform",
            "is_main_framework": True,
            "related_frameworks": []
        },
        "React Native": {
            "file_patterns": [r"node_modules/react-native", r"\.js$", r"\.jsx$", r"\.ts$", r"\.tsx$"],
            "search_patterns": [r"react-native", r"import.*React", r"from\s+['\"]react['\"]"],
            "category": "Cross-Platform",
            "is_main_framework": True,
            "related_frameworks": ["JavaScript"]
        },
        "Xamarin": {
            "file_patterns": [r"\.xaml$", r"\.cs$"],
            "search_patterns": [r"Xamarin", r"MonoTouch"],
            "category": "Cross-Platform",
            "is_main_framework": True,
            "related_frameworks": [".NET"]
        },
        "Unity": {
            "files": [
                r".*Unity.*\.framework$",
                r".*\.unity3d$",
                r".*UnityAppController\.h$",
                r".*\/Unity\/.*"
            ],
            "patterns": [
                r"UnityFramework",
                r"UnityAppController",
                r"UnitySendMessage"
            ],
            "category": "游戏引擎",
            "is_main_framework": True,
            "features": ["跨平台游戏引擎", "3D/2D游戏开发", "C#编程"]
        },
        "Unreal Engine": {
            "files": [
                r".*\.uproject$",
                r".*\.uasset$",
                r".*UE4CommandLine\.txt$",
                r".*\/UE4\/.*",
                r".*\/UnrealEngine\/.*"
            ],
            "patterns": [
                r"FIOSApplication",
                r"FIOSPlatformMisc",
                r"UnrealEngine"
            ],
            "category": "游戏引擎",
            "is_main_framework": True,
            "features": ["高品质3D游戏引擎", "C++编程", "蓝图可视化编程"]
        },
        "Cocos2d-x": {
            "files": [
                r".*cocos2d.*\.framework$",
                r".*\/cocos2d\/.*",
                r".*\/cocos2dx\/.*"
            ],
            "patterns": [
                r"cocos2d::",
                r"CCDirector",
                r"CCScene"
            ],
            "category": "游戏引擎",
            "is_main_framework": True,
            "features": ["轻量级2D游戏引擎", "C++/Objective-C编程", "跨平台开发"]
        },
        "Godot": {
            "files": [
                r".*\.godot$",
                r".*\.tscn$",
                r".*\.gdscript$",
                r".*godot_ios\.h$"
            ],
            "patterns": [
                r"GodotIOSPlugin",
                r"GodotApp",
                r"extends Node"
            ],
            "category": "游戏引擎",
            "is_main_framework": True,
            "features": ["开源游戏引擎", "GDScript编程", "节点系统", "2D/3D游戏开发"]
        },
        "GameMaker": {
            "files": [
                r".*YoYoIOS.*\.h$",
                r".*YYGameMakerYY.*"
            ],
            "patterns": [
                r"YYGameMakerYY",
                r"GMResource",
                r"YoYoGames"
            ],
            "category": "游戏引擎",
            "is_main_framework": True,
            "features": ["易用性高的游戏开发工具", "GML编程语言", "视觉化编辑器"]
        },
        "LibGDX": {
            "files": [
                r".*gdx.*\.framework$",
                r".*\/libgdx\/.*",
                r".*\.gdx$"
            ],
            "patterns": [
                r"libgdx",
                r"com\.badlogic\.gdx",
                r"gdx\.app"
            ],
            "category": "游戏引擎",
            "is_main_framework": True,
            "features": ["Java游戏开发框架", "跨平台", "2D/3D游戏开发", "开源"]
        },
        "SpriteKit": {
            "files": [".sks"],
            "patterns": ["SKScene", "import SpriteKit"],
            "category": "游戏引擎",
            "is_main_framework": True,
            "features": ["2D游戏开发", "物理引擎", "粒子系统", "苹果原生支持"]
        },
        "SceneKit": {
            "files": [".scn"],
            "patterns": ["SCNScene", "import SceneKit"],
            "category": "游戏引擎",
            "is_main_framework": True,
            "features": ["3D游戏开发", "物理引擎", "粒子系统", "苹果原生支持"]
        },
        "Metal": {
            "file_patterns": [r"\.metal$", r"MetalKit", r"\.mtl$"],
            "search_patterns": [r"import\s+Metal", r"MTLDevice", r"MTLRenderPipelineState", r"MTLBuffer"],
            "category": "Game",
            "is_main_framework": True,
            "related_frameworks": ["Foundation", "CoreGraphics"]
        },
        "Objective-C": {
            "file_patterns": [r"\.h$", r"\.m$"],
            "search_patterns": [r"@interface", r"@implementation", r"#import"],
            "category": "Language",
            "is_main_framework": False,
            "related_frameworks": ["Foundation", "UIKit"]
        },
        "Swift": {
            "file_patterns": [r"\.swift$"],
            "search_patterns": [r"import", r"struct", r"class", r"func"],
            "category": "Language",
            "is_main_framework": False,
            "related_frameworks": ["Foundation", "Combine"]
        },
        "CoreData": {
            "file_patterns": [r"\.xcdatamodeld$", r"\.xcdatamodel$"],
            "search_patterns": [r"import\s+CoreData", r"NSManagedObject", r"NSPersistentContainer"],
            "category": "Data",
            "is_main_framework": False,
            "related_frameworks": ["Foundation"]
        },
        "Realm": {
            "file_patterns": [r"\.realm$"],
            "search_patterns": [r"import\s+RealmSwift", r"import\s+Realm", r"class.*:.*Object"],
            "category": "Data",
            "is_main_framework": False,
            "related_frameworks": []
        },
        "Firebase": {
            "file_patterns": [r"GoogleService-Info\.plist$"],
            "search_patterns": [r"import\s+Firebase", r"FirebaseApp\.configure"],
            "category": "Backend",
            "is_main_framework": False,
            "related_frameworks": []
        },
        "MapKit": {
            "file_patterns": [r"MKMapView"],
            "search_patterns": [r"import\s+MapKit", r"MKMapView", r"MKAnnotation"],
            "category": "Map",
            "is_main_framework": False,
            "related_frameworks": ["UIKit", "CoreLocation"]
        },
        "Foundation": {
            "file_patterns": [r"\.swift$", r"\.m$", r"\.h$"],
            "search_patterns": [r"import\s+Foundation", r"NSString", r"NSArray", r"NSDictionary", r"NSData"],
            "category": "Core",
            "is_main_framework": False,
            "related_frameworks": []
        },
        "CoreGraphics": {
            "file_patterns": [r"\.swift$", r"\.m$", r"\.h$"],
            "search_patterns": [r"import\s+CoreGraphics", r"CGRect", r"CGPoint", r"CGSize", r"CGContext"],
            "category": "Graphics",
            "is_main_framework": False,
            "related_frameworks": ["UIKit", "Foundation"]
        },
        "CoreLocation": {
            "file_patterns": [r"\.swift$", r"\.m$", r"\.h$"],
            "search_patterns": [r"import\s+CoreLocation", r"CLLocationManager", r"CLLocation"],
            "category": "Location",
            "is_main_framework": False,
            "related_frameworks": ["Foundation", "MapKit"]
        },
        "阿里Weex": {
            "file_patterns": [r"WeexSDK\.framework$", r"weex\-main\.js$"],
            "search_patterns": [
                r"WXSDKEngine",
                r"WXSDKInstance",
                r"#import\s+<WeexSDK/",
                r"import\s+WeexSDK"
            ],
            "category": "跨平台框架",
            "is_main_framework": True,
            "related_frameworks": ["Foundation"],
            "features": ["阿里巴巴开发的跨平台框架", "类似React Native的开发体验", "高性能渲染"]
        },
        "腾讯MMKV": {
            "file_patterns": [r"MMKV\.framework$", r"libMMKV\.a$"],
            "search_patterns": [
                r"MMKV\.h",
                r"#import\s+<MMKV/",
                r"import\s+MMKV",
                r"MMKV\.default"
            ],
            "category": "数据存储",
            "is_main_framework": False,
            "related_frameworks": [],
            "features": ["腾讯开发的高性能键值存储框架", "基于mmap的存储方式", "跨平台支持"]
        },
        "腾讯WeTest": {
            "file_patterns": [r"WeTest\.framework$", r"libWeTest\.a$"],
            "search_patterns": [
                r"WeTestSDK",
                r"#import\s+<WeTest/",
                r"import\s+WeTest"
            ],
            "category": "应用测试",
            "is_main_framework": False,
            "related_frameworks": [],
            "features": ["腾讯开发的应用测试框架", "自动化测试", "性能测试"]
        },
        "腾讯Bugly": {
            "file_patterns": [r"Bugly\.framework$", r"libBugly\.a$"],
            "search_patterns": [
                r"BuglyConfig",
                r"#import\s+<Bugly/",
                r"import\s+Bugly",
                r"Bugly\.start"
            ],
            "category": "应用监控",
            "is_main_framework": False,
            "related_frameworks": [],
            "features": ["腾讯开发的应用监控框架", "崩溃分析", "运行时异常捕获"]
        },
        "华为HMS": {
            "file_patterns": [r"HMSCORE\.framework$", r"AGConnectCore\.framework$"],
            "search_patterns": [
                r"HMSCore",
                r"AGConnectCore",
                r"#import\s+<HMSCORE/",
                r"import\s+AGConnect"
            ],
            "category": "移动服务",
            "is_main_framework": False,
            "related_frameworks": [],
            "features": ["华为移动服务iOS版", "推送通知", "地图服务", "分析服务"]
        },
        "百度地图SDK": {
            "file_patterns": [r"BaiduMapAPI.*\.framework$", r"libBaiduMapAPI.*\.a$"],
            "search_patterns": [
                r"BMKMapView",
                r"#import\s+<BaiduMapAPI",
                r"import\s+BaiduMapAPI"
            ],
            "category": "地图服务",
            "is_main_framework": False,
            "related_frameworks": ["CoreLocation"],
            "features": ["百度地图服务", "位置搜索", "路线规划", "地图显示"]
        },
        "阿里支付宝SDK": {
            "file_patterns": [r"AlipaySDK\.framework$", r"libAlipaySDK\.a$"],
            "search_patterns": [
                r"AlipaySDK",
                r"#import\s+<AlipaySDK/",
                r"import\s+AlipaySDK"
            ],
            "category": "支付服务",
            "is_main_framework": False,
            "related_frameworks": [],
            "features": ["支付宝支付服务", "快捷支付", "安全支付"]
        },
        "腾讯微信SDK": {
            "file_patterns": [r"WechatOpenSDK\.framework$", r"libWeChatSDK\.a$"],
            "search_patterns": [
                r"WXApi",
                r"#import\s+<WechatOpenSDK/",
                r"import\s+WechatOpenSDK"
            ],
            "category": "社交服务",
            "is_main_framework": False,
            "related_frameworks": [],
            "features": ["微信登录", "微信支付", "微信分享"]
        },
        "UCloud-友盟SDK": {
            "file_patterns": [r"UMCommon\.framework$", r"UMAnalytics\.framework$"],
            "search_patterns": [
                r"UMCommon",
                r"#import\s+<UMCommon/",
                r"import\s+UMCommon"
            ],
            "category": "应用分析",
            "is_main_framework": False,
            "related_frameworks": [],
            "features": ["友盟应用分析服务", "用户行为分析", "设备统计", "推送服务"]
        },
        "极光推送": {
            "file_patterns": [r"JPush\.framework$", r"libjpush\-ios\-.*\.a$"],
            "search_patterns": [
                r"JPUSHService",
                r"#import\s+<JPush/",
                r"import\s+JPush"
            ],
            "category": "推送服务",
            "is_main_framework": False,
            "related_frameworks": [],
            "features": ["极光推送服务", "推送统计", "用户标签"]
        },
        "网易云信": {
            "file_patterns": [r"NIMSDK\.framework$", r"libNIMSDK\.a$"],
            "search_patterns": [
                r"NIMSDK",
                r"#import\s+<NIMSDK/",
                r"import\s+NIMSDK"
            ],
            "category": "通信服务",
            "is_main_framework": False,
            "related_frameworks": [],
            "features": ["即时通讯", "音视频通话", "聊天室"]
        },
        "uni-app": {
            "file_patterns": [r"uni\-jsframework\.js$", r"uni\-app.*\.js$", r"lib/plus/", r"pages\.json$"],
            "search_patterns": [
                r"uni\-app",
                r"uni\.",
                r"getApp\(\)",
                r"uniCloud", 
                r"uts"
            ],
            "category": "跨平台框架",
            "is_main_framework": True,
            "related_frameworks": ["WebKit"],
            "features": ["DCloud开发的跨平台框架", "使用Vue.js开发", "一套代码多端运行", "国内流行的小程序开发方案"]
        },
        "uView": {
            "file_patterns": [r"uview.*\.js$", r"uview.*\.vue$", r"uview\-ui"],
            "search_patterns": [
                r"uview\-ui",
                r"import uView from",
                r"u\-"
            ],
            "category": "UI组件库",
            "is_main_framework": False,
            "related_frameworks": ["uni-app"],
            "features": ["uni-app生态的UI框架", "丰富的组件", "中文文档完善", "国内广泛使用"]
        }
    }

    def __init__(self, app_path: str, config: dict = None, verbose: bool = False):
        """
        初始化iOS应用分析器
        
        Args:
            app_path: 应用程序路径
            config: 配置信息
            verbose: 是否输出详细日志
        """
        super().__init__(app_path, config, verbose)
        self.logger = get_logger("IOSAnalyzer")
        self.logger.info(f"初始化iOS应用分析器: {app_path}")
        
        # 合并配置和默认框架特征
        self.framework_signatures = self.FRAMEWORK_SIGNATURES.copy()
        if config and "frameworks" in config:
            for fw_name, fw_data in config["frameworks"].items():
                if fw_name in self.framework_signatures:
                    # 更新现有框架
                    for key, values in fw_data.items():
                        if key in self.framework_signatures[fw_name]:
                            if isinstance(self.framework_signatures[fw_name][key], list):
                                self.framework_signatures[fw_name][key].extend(values)
                            else:
                                self.framework_signatures[fw_name][key] = values
                        else:
                            self.framework_signatures[fw_name][key] = values
                else:
                    # 添加新框架
                    self.framework_signatures[fw_name] = fw_data

    def analyze(self) -> AnalysisResult:
        """分析iOS应用程序，检测使用的框架"""
        self.logger.info(f"开始分析iOS应用: {self.app_path}")
        start_time = time.time()
        
        # 获取应用基本信息
        app_info = self.detect_app_info()
        
        # 创建分析结果对象
        result = AnalysisResult(
            app_info=app_info,
            platform="iOS",
            analyzer=self.__class__.__name__
        )
        
        # 扫描所有文件
        files = list(self.scan_files())
        self.logger.info(f"找到{len(files)}个文件")
        
        # 在代码中查找框架特征
        for name, signature in self.framework_signatures.items():
            self.logger.debug(f"检查框架: {name}")
            matched_files = []
            
            # 获取文件和搜索模式
            file_patterns = signature.get('files', [])
            search_patterns = signature.get('patterns', [])
            
            # 使用search_signatures方法查找匹配
            matches = self.search_signatures(files, file_patterns, search_patterns)
            
            if matches:
                self.logger.info(f"检测到框架 {name}，匹配文件数: {len(matches)}")
                
                # 计算置信度 - 基于匹配的数量
                confidence = min(40 + len(matches) * 10, 95)
                
                # 创建框架信息对象
                framework = FrameworkInfo(
                    name=name,
                    version=None,  # 版本信息需要进一步分析
                    confidence=confidence,
                    files=matches,
                    is_main_framework=signature.get('is_main_framework', False),
                    category=signature.get('category', '未分类')
                )
                
                # 添加到结果中
                result.add_framework(framework)
        
        # 分析框架之间的关系
        self.analyze_framework_relationships(result)
        
        # 计算分析时间
        end_time = time.time()
        analysis_time = end_time - start_time
        result.analysis_time = analysis_time
        
        self.logger.info(f"iOS应用分析完成，耗时: {analysis_time:.2f}秒，"
                         f"检测到{len(result.frameworks)}个框架")
        
        return result
    
    def analyze_framework_relationships(self, result: AnalysisResult) -> None:
        """分析框架之间的关系并添加相关信息到分析结果"""
        self.logger.debug("分析框架关系")
        
        # 获取已检测到的框架
        detected_frameworks = {f.name: f for f in result.frameworks}
        
        # 定义框架依赖关系
        framework_relationships = {
            "UIKit": ["Objective-C"],  # UIKit基于Objective-C
            "SwiftUI": ["Swift"],      # SwiftUI基于Swift
            "CoreData": ["Objective-C", "Swift"],  # CoreData可与Objective-C或Swift一起使用
            "Realm": ["Objective-C", "Swift"],     # Realm可与Objective-C或Swift一起使用
            "Firebase": ["Objective-C", "Swift"],  # Firebase可与Objective-C或Swift一起使用
            "MapKit": ["UIKit"],       # MapKit依赖于UIKit
        }
        
        # 分析UI框架的可能使用
        ui_frameworks = [f for f in detected_frameworks if detected_frameworks[f].category == "UI框架"]
        
        # 如果检测到SwiftUI，增加Swift的置信度
        if "SwiftUI" in detected_frameworks and "Swift" in detected_frameworks:
            swift_framework = detected_frameworks["Swift"]
            swift_framework.confidence = min(95, swift_framework.confidence + 15)
            self.logger.debug("检测到SwiftUI，增加Swift的置信度")
        
        # 如果检测到UIKit，增加Objective-C的置信度
        if "UIKit" in detected_frameworks and "Objective-C" in detected_frameworks:
            objc_framework = detected_frameworks["Objective-C"]
            objc_framework.confidence = min(95, objc_framework.confidence + 10)
            self.logger.debug("检测到UIKit，增加Objective-C的置信度")
        
        # 处理框架依赖关系
        for framework, dependencies in framework_relationships.items():
            if framework in detected_frameworks:
                for dependency in dependencies:
                    if dependency in detected_frameworks:
                        # 增加依赖框架的置信度
                        dep_framework = detected_frameworks[dependency]
                        dep_framework.confidence = min(95, dep_framework.confidence + 5)
                        self.logger.debug(f"框架 {framework} 依赖于 {dependency}，增加其置信度")
        
        # 更新框架列表以反映置信度变化
        result.frameworks = list(detected_frameworks.values())

    def detect_app_info(self) -> AppInfo:
        """尝试从Info.plist文件提取应用信息"""
        try:
            # 查找Info.plist文件
            info_plist_path = None
            for file in self.scan_files():
                if file.name == "Info.plist":
                    info_plist_path = file
                    break
            
            if not info_plist_path:
                self.logger.warning("未找到Info.plist文件")
                return AppInfo(name="Unknown", version="Unknown", package_name="Unknown")
            
            # 解析Info.plist文件
            try:
                # 尝试加载二进制plist
                with open(info_plist_path, 'rb') as f:
                    plist_data = plistlib.load(f)
            except:
                # 尝试加载文本plist
                with open(info_plist_path, 'r', encoding='utf-8') as f:
                    plist_content = f.read()
                    # 使用正则表达式提取值
                    app_name = re.search(r'<key>CFBundleName</key>\s*<string>(.*?)</string>', plist_content)
                    app_version = re.search(r'<key>CFBundleShortVersionString</key>\s*<string>(.*?)</string>', plist_content)
                    bundle_id = re.search(r'<key>CFBundleIdentifier</key>\s*<string>(.*?)</string>', plist_content)
                    
                    return AppInfo(
                        name=app_name.group(1) if app_name else "Unknown",
                        version=app_version.group(1) if app_version else "Unknown",
                        package_name=bundle_id.group(1) if bundle_id else "Unknown"
                    )
            
            # 从plist_data提取信息
            app_info = AppInfo(
                name=plist_data.get('CFBundleName', plist_data.get('CFBundleDisplayName', 'Unknown')),
                version=plist_data.get('CFBundleShortVersionString', 'Unknown'),
                package_name=plist_data.get('CFBundleIdentifier', 'Unknown')
            )
            
            self.logger.info(f"提取的应用信息: {app_info.to_dict()}")
            return app_info
        
        except Exception as e:
            self.logger.error(f"检测应用信息时出错: {str(e)}")
            return AppInfo(name="Unknown", version="Unknown", package_name="Unknown")
